#pragma once

#include <string.h>
#include <string>
#include <time.h>
#include <map>
#include <memory>
#include <functional>

#define WLogi(fmt, ...) {time_t timep; time(&timep); struct tm *p = localtime(&timep); printf("%4d-%02d-%02d %02d:%02d:%02d [%llu][I] ", 1900+p->tm_year, 1+p->tm_mon, p->tm_mday, p-> tm_hour, p->tm_min, p->tm_sec, (unsigned long long)pthread_self());printf(fmt, ##__VA_ARGS__);printf("\n");fflush(stdout);}
#define WLogw(fmt, ...) {time_t timep; time(&timep); struct tm *p = localtime(&timep); printf("%4d-%02d-%02d %02d:%02d:%02d [%llu][W] ", 1900+p->tm_year, 1+p->tm_mon, p->tm_mday, p-> tm_hour, p->tm_min, p->tm_sec, (unsigned long long)pthread_self());printf(fmt, ##__VA_ARGS__);printf("\n");fflush(stdout);}
#define WLoge(fmt, ...) {time_t timep; time(&timep); struct tm *p = localtime(&timep); printf("%4d-%02d-%02d %02d:%02d:%02d [%llu][E] ", 1900+p->tm_year, 1+p->tm_mon, p->tm_mday, p-> tm_hour, p->tm_min, p->tm_sec, (unsigned long long)pthread_self());printf(fmt, ##__VA_ARGS__);printf("\n");fflush(stdout);}

#ifdef WIN32
    #define strcasecmp _stricmp
    #define strncasecmp _strnicmp
#endif
// 不区分大小写的比较器
struct HeaderCaseCompare
{
    bool operator() (const std::string& lhs, const std::string& rhs) const
    {
        return strcasecmp(lhs.c_str(), rhs.c_str()) < 0;
    }
};

// 请求消息结构体
struct HttpClientReqMsg {
    std::string method; // GET POST PUT DELETE
    std::string uri; // for example: /api/rest/getName
    std::map<std::string, std::string> querys; // the params in uri
    std::map<std::string, std::string, HeaderCaseCompare> headers; // 不区分大小写的map
    std::string body;
};

// 响应消息结构体
struct HttpClientRspMsg {
    std::map<std::string, std::string, HeaderCaseCompare> headers;
    std::string body;
    std::shared_ptr<std::string> chunk;
    int64_t totalBodySize;
    int64_t recvChunkSize = 0;
    bool finishRecvChunk = false;
    int code = 0; // http消息返回的状态码，比如200，500
    int errStatus = 0; // 0表示成功，其它值表示失败
};

using HttpClientCbFun = std::function<void(std::shared_ptr<HttpClientRspMsg> &)>;

class WHttpClientCommon
{
public:
    static int64_t str2ll(const std::string &str, int64_t errValue = 0);
    static std::string urlEncode(const std::string& input, bool isFormEncoded = false);
    static std::string urlDecode(const std::string& input, bool isFormEncoded = false);
    static int hexToInt(char c);
};
